#include "gt_iic.h"
#include "lcd_fsmc.h"

/*  
    GT1151Q触摸屏驱动代码
*/

// 触摸屏关键数据
tp_device tp_dev;

// 命令数组
uint16_t PointReg[5] = {
    Point1Reg,
    Point2Reg,
    Point3Reg,
    Point4Reg,
    Point5Reg
}; 

/***********************底层实现************************/

void IIC_Delay(void)
{
    uint16_t count = 1000;
    while(count--)
    {
        count = count;
    }
}

// IIC起始信号
void GT_IIC_Start(void)
{
    IIC_SDA_SET(1);
    IIC_SCL_SET(1);
    IIC_Delay();
    IIC_SDA_SET(0);
    IIC_Delay();
    IIC_SCL_SET(0);
    IIC_Delay();
}


// IIC结束信号
void GT_IIC_Stop(void)
{
    IIC_SCL_SET(0);
    IIC_SDA_SET(0);
    IIC_Delay();
    IIC_SCL_SET(1);
    IIC_Delay();
    IIC_SDA_SET(1);
    IIC_Delay();
}

// 触摸芯片 IIC初始化
void GT_IIC_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    // 使能IIC引脚的时钟
    RCC_AHB1PeriphClockCmd(IIC_CLK,ENABLE);
    //  SCL推挽输出
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = IIC_SCL;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IIC_PORT,&GPIO_InitStruct);

    // SDA开漏输出
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStruct.GPIO_Pin = IIC_SDA;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IIC_PORT,&GPIO_InitStruct);

    // 总线空闲
    GT_IIC_Stop();
}



// 主机发送应答
void GT_IIC_Ack(void)
{
    IIC_SDA_SET(0);
    IIC_Delay();
    IIC_SCL_SET(1);
    IIC_Delay();
    IIC_SCL_SET(0);     // 为下次数据发送做准备
    IIC_Delay();
    IIC_SDA_SET(1); // 释放总线
}


// 主机发送非应答
void GT_IIC_NAck(void)
{
    IIC_SDA_SET(1);
    IIC_Delay();
    IIC_SCL_SET(1);
    IIC_Delay();
    IIC_SCL_SET(0);
    IIC_Delay();
}

// 主机等待从机应答
uint8_t GT_IIC_WaitAck(void)
{
    uint16_t count = 300;
    // 释放总线
    IIC_SDA_SET(1);
    IIC_Delay();
    // 拉高SCL读取从机
    IIC_SCL_SET(1);
    IIC_Delay();
    while(READ_SDA)
    {
        if(!count--)
        {
            return IIC_NACK;
        }
    }
    // 结束SCL拉高
    IIC_SCL_SET(0);
    IIC_Delay();
    return IIC_ACK;
}

// 主机发送一个字节数据
void GT_IIC_SendByte(uint8_t Byte)
{
    uint8_t i;
    for(i = 0; i < 8; i++)
    {
        if(Byte & (0x80 >> i))
        {
            IIC_SDA_SET(1);
        }else{
            IIC_SDA_SET(0);
        }
        IIC_Delay();
        IIC_SCL_SET(1);
        IIC_Delay();
        IIC_SCL_SET(0);
    }
    IIC_SDA_SET(1); // 释放SDA，让从机应答
}

// 主机接收一个字节数据
uint8_t GT_IIC_ReadByte(uint8_t ack)
{
    uint8_t i,receive  = 0;
    IIC_SDA_SET(1); // 释放总线
    for(i = 0; i < 8; i++)
    {
        receive <<= 1;
        IIC_SCL_SET(1);
        IIC_Delay();
        if(READ_SDA)
        {
            receive++;
        }
        IIC_SCL_SET(0);
        IIC_Delay();
    }
    if(ack == IIC_ACK)
    {
        GT_IIC_Ack();
    }else{
        GT_IIC_NAck();
    }
    return receive;
}


/*****************芯片使用**************/




// 主机写n个字节
uint8_t GT_Write_Reg(uint8_t *buf,uint8_t size,uint16_t addr)
{
    uint8_t i;
    uint8_t ret = 0;
    GT_IIC_Start();
    GT_IIC_SendByte(GT_WRITE_ADDR);
    GT_IIC_WaitAck();
    GT_IIC_SendByte(addr >> 8);
    GT_IIC_WaitAck();
    GT_IIC_SendByte(addr & 0xFF);
    GT_IIC_WaitAck();
    for(i = 0; i < size; i++)
    {
        GT_IIC_SendByte(buf[i]);
        ret = GT_IIC_WaitAck();
        if(ret != IIC_ACK) break;
    }
    GT_IIC_Stop();
    return ret;
}

// 主机读n个字节
void GT_Read_Reg(uint8_t *buf, uint8_t size, uint16_t addr)
{
    uint8_t i;
    GT_IIC_Start();
    GT_IIC_SendByte(GT_WRITE_ADDR);
    GT_IIC_WaitAck();
    GT_IIC_SendByte(addr >> 8);
    GT_IIC_WaitAck();
    GT_IIC_SendByte(addr & 0xFF);
    GT_IIC_WaitAck();
    GT_IIC_Start();
    GT_IIC_SendByte(GT_READ_ADDR);
    GT_IIC_WaitAck();
    for(i = 0; i < size-1; i++)
    {
        buf[i] = GT_IIC_ReadByte(0);
    }
    buf[i] = GT_IIC_ReadByte(1);
    GT_IIC_Stop();
}


// 触摸屏初始化
// 成功返回1，失败返回0
uint8_t GT1151Q_Init(void)
{
    uint8_t temp[4];
    uint8_t state = 0;
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHB1PeriphClockCmd(RST_CLK | INT_CLK,ENABLE);
    // RST推挽输出
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = RST_PIN;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(RST_PORT,&GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_Pin = INT_PIN;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(INT_PORT,&GPIO_InitStruct);

    // 初始化IIC
    GT_IIC_Init();
    // 复位
    RST_SET(0);
    IIC_Delay();
    RST_SET(1);
    IIC_Delay();

    // 清除状态寄存器
    GT_Write_Reg(&state,1,StatusReg);

    // 读取产品ID
    GT_Read_Reg(temp,4,ProductID);
    if(temp[0] == '1' && temp[1] == '1' && \
        temp[2] == '5' && temp[3] == '8')
        return 1;
    return 0;
}


// 扫描触摸
// 返回1表示有坐标读取,返回0表示没有坐标读取
uint8_t Touch_Scan(void)
{
    uint8_t state;
    uint8_t i;
    uint8_t point[4] = {0};
    GT_Read_Reg(&state,1,StatusReg);
    state = state & 0x0F;
    tp_dev.fg_num = state;
    state = 0;
    GT_Write_Reg(&state,1,StatusReg);
    //循环获取触摸点数据
    for(i = 0; i < tp_dev.fg_num; i++)
    {
        GT_Read_Reg(point,4,PointReg[i]);
        if(lcddev.DIR == 0)
        {
            tp_dev.x[i] = (uint16_t)(point[1] << 8) + point[0];
            tp_dev.y[i] = (uint16_t)(point[3] << 8) + point[2];
        }
        else{
            // 根据显示屏方向调整坐标
            tp_dev.y[i] = lcddev.LCD_Height-((uint16_t)(point[1] << 8) + point[0]);
            tp_dev.x[i] = ((uint16_t)(point[3] << 8) + point[2]);
        }
        if(tp_dev.x[i] > lcddev.LCD_Width || tp_dev.y[i] > lcddev.LCD_Height)
            return 0;
    }
    return tp_dev.fg_num>0?1:0;
}

